
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from oauth.models import OAuthQQUser
from oauth.utils import check_encrypted_openid
from users.models import User


class QQUserSerializer(serializers.Serializer):
    '''QQ登录创建用户序列化器'''
    openid = serializers.CharField(label='openid', write_only=True)
    mobile = serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$', write_only=True)
    password = serializers.CharField(label='密码', max_length=20, min_length=8, write_only=True)
    sms_code = serializers.CharField(label='手机验证码', write_only=True)

    def validate(self, attrs):
        # 获取openid, 校验openid是否有效
        encrypted_openid = attrs['openid']
        openid = check_encrypted_openid(encrypted_openid)
        if not openid:
            raise ValidationError({'message': '无效的openid'})
        # 修改字典中openid的值， 以便保存正确的openid到映射表
        attrs['openid'] = openid

        mobile = attrs['mobile']
        sms_code = attrs['sms_code']
        password = attrs['password']

        # 校验短信验证码
        redis_conn = get_redis_connection('sms_codes')
        mobile = attrs['mobile']
        real_sms_code = redis_conn.get('sms_%s' % mobile)
        if real_sms_code is None:
            raise ValidationError('无效的短信验证码')
        if attrs['sms_code'] != real_sms_code.decode():
            raise ValidationError('短信验证码错误')

        # 根据手机号查询美多用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            # 如果用户不存在，则以手机号作为用户名，创建美多用户
            user = User.objects.create_user(
                username=mobile,
                password=password,
                mobile=mobile
            )
        else:
            # 如果要绑定的用户存在，则校验密码是否正确
            if not user.check_password(password):
                raise ValidationError({'message': '密码错误'})

        # 将认证后的user放进校验字典中，绑定关联时用到
        attrs['user'] = user
        return attrs

    def create(self, validated_data):
        # 获取校验的用户
        user = validated_data.get('user')
        openid = validated_data.get('openid')

        OAuthQQUser.objects.create(
            openid=openid,
            user=user
        )
        return user
